package cn.zwx.common.retry.config.services;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.retry.support.RetryTemplate;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
 * @author zhangwenxue
 */
@ConditionalOnProperty(name = "cn.zwx.retry.async",havingValue="true")
public class AsyncRetryService {

    public static final Logger logger  = LoggerFactory.getLogger(AsyncRetryService.class);
    private final RetryTemplate retryTemplate;
    private final Executor customTaskExecutor;


    public AsyncRetryService(RetryTemplate retryTemplate, @Qualifier(value = "retryExecutor")Executor customTaskExecutor) {
        this.retryTemplate = retryTemplate;
        this.customTaskExecutor = customTaskExecutor;
    }

    public <T> CompletableFuture<T> executeWithRetry(Supplier<T> retry,Supplier<T> recover) {
        return CompletableFuture.supplyAsync(() -> retryTemplate.execute(retryContext -> retry.get(),
                retryContext ->{
                    final Thread thread = Thread.currentThread();
                    logger.error("thread_id:{},thread_name:{},超过最大重试次数,最大重试次数:{}",thread.getId(),thread.getName(), retryContext.getRetryCount(), retryContext.getLastThrowable());
                    return recover.get();
                }

        ), customTaskExecutor);
    }

}
